/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.agent.service;

import cn.ac.iie.agent.tools.FtpTools;
import cn.ac.iie.agent.tools.LoadMapData;
import cn.ac.iie.agent.tools.PropsFiles;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;

/**
 *
 * @author dell
 */
public class FtpDownloadJsonFilesThread {

    private static Logger logger = Logger.getLogger(FtpDownloadJsonFilesThread.class);
    private String subjobid;
    private String ip;
    private String port;
    private String username;
    private String password;
    private String filepath;
    private String jsonfiles;
    private long complete = 0;//完成上传的文件数
    Map<String, String> rsMap;

    public FtpDownloadJsonFilesThread(String subjobid, String ip, String port, String username, String password, String filepath, String jsonfiles, Map<String, String> rsMap) {
        this.subjobid = subjobid;
        this.ip = ip;
        this.port = port;
        this.username = username;
        this.password = password;
        this.filepath = filepath;
        this.jsonfiles = jsonfiles;
        this.rsMap = rsMap;
    }

    public void execute() {
        PropsFiles ps = new PropsFiles();
        FtpTools ftpTools = new FtpTools();
        logger.info(subjobid + " ip: " + ip + " ,port: " + port + " ,username: " + username + " ,password: " + password + " ,filepath: " + filepath);
        if (!filepath.endsWith("/")) {
            filepath += "/";
        }

        String[] str = filepath.split("/");
        String namespace = str[str.length - 1];//0_shipin
        String realnamespace = namespace.substring(namespace.indexOf("_") + 1, namespace.length());//shipin
        logger.info(subjobid + " ip: " + ip + " namespace is " + namespace);

        //本地下载路径
        String path = ps.getValue("downloadFilePathRoot");
        if (!path.endsWith("/")) {
            path += "/";
        }

        //根据ip获取数据来源datasouce.mapdata
        String localFilePath = "";//本地采集路径xx/企业类型/ToPlatForm/xxxx
        for (Iterator columnsit = LoadMapData.dataMapHashMaps.entrySet().iterator(); columnsit.hasNext();) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) columnsit.next();
            logger.debug(subjobid + entry.getKey() + ": (ip)" + entry.getValue());
            if (entry.getKey().equals(ip)) {
                logger.info(subjobid + " the ip is: " + ip);
                localFilePath = path + entry.getValue() + "/" + filepath;//确定到namespace
                break;
            }
        }
        logger.info("the local download path is: " + localFilePath);
        String ftpErrorPath = "/" + namespace + "/" + ps.getValue("ErrorType") + "/";//从namespace开始
        logger.info(subjobid + " ip: " + ip + " localFilePath: " + localFilePath + " ,ftperrorpath:" + ftpErrorPath);

        boolean downloadJsonflag = false;
        String[] jsonFiles = new String[]{};
        if (!localFilePath.isEmpty()) {
            //下载JSON文件
            jsonFiles = jsonfiles.split("\\|");
            logger.debug(subjobid + " ip: " + ip + " download!download!");
//            for (int m = 0; m < jsonFiles.length; m++) {
//                logger.info(subjobid + " ip: " + ip + " download!download! " + jsonFiles[m]);
//            }
            downloadJsonflag = ftpTools.downJsonFile(ip, Integer.parseInt(port), username, password, filepath + "Ctrl", localFilePath + "Ctrl", jsonFiles);
        }

        if (downloadJsonflag) {
            //解析json文件
            logger.info(subjobid + " ip: " + ip + " prepare to parse json file!");
            //目录下获取ctrl文件
            File ctrlDir = new File(localFilePath + "Ctrl");
            if (!ctrlDir.exists()) {
                logger.info(subjobid + " ip: " + ip + " the local JSON file path does not exist.");
            } else {
                File[] ctrlFiles = ctrlDir.listFiles();
                List<File> okList = new ArrayList<File>();
                if (ctrlFiles.length != 0) {
                    logger.info(subjobid + " ip: " + ip + " the path of： " + localFilePath + "Ctrl has " + ctrlFiles.length + " files.");
                    for (int i = 0; i < ctrlFiles.length; i++) {
                        if (ctrlFiles[i].getName().endsWith(".ok")) {
                            okList.add(ctrlFiles[i]);
                        }
                    }

                    //起线程池
                    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Integer.parseInt(ps.getValue("coreThreadPoolSize")), Integer.parseInt(ps.getValue("maxThreadPoolSize")), 3,
                            TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(Integer.parseInt(ps.getValue("workQueueSize"))),
                            new ThreadPoolExecutor.DiscardOldestPolicy());

                    for (int i = 0; i < jsonFiles.length; i++) {
                        boolean existflag = false;
                        String okname = jsonFiles[i] + ".ok";
                        for (int j = 0; j < okList.size(); j++) {
                            if (okname.equals(okList.get(j).getName())) {
                                existflag = true;
                                break;
                            }
                        }

                        if (!existflag) {
                            logger.info(subjobid + " ip: " + ip + " start to analyze the JSON file and download the data files by JSON file: " + jsonFiles[i] + " and the localFilePath is " + localFilePath + "Ctrl ,the dataPath is " + filepath + "Data");
                            //解析json文件，下载数据文件（若失败，写并上传失败json文件）
                            threadPool.execute(new FtpDownloadDataFilesThread(subjobid, jsonFiles[i], ip, Integer.parseInt(port), username, password, localFilePath, filepath, realnamespace, ftpErrorPath, this));
                        } else {
                            logger.info(subjobid + " ip: " + ip + " ***********************the local path already has the JSON file: " + jsonFiles[i]);
                            boolean dwdFile = ftpTools.dwdFile(ip, Integer.parseInt(port), username, password, filepath + "Ctrl", jsonFiles[i], realnamespace);
                            logger.info(subjobid + " ip: " + ip + " ***********************upload dwd JSON file return " + dwdFile);
                        }
                    }
                    //timeout
                    long begin = System.currentTimeMillis();
                    while (true) {//直至所有线程结束，才继续
                        int activeThread = threadPool.getActiveCount();
                        if (activeThread == 0) {
                            logger.info(subjobid + " ip: " + ip + " threadPool.getActiveCount()==0 break");
                            break;
                        } else {
                            logger.info(subjobid + " ip: " + ip + " threadPool.getActiveCount()!=0 " + activeThread);
                            long end = System.currentTimeMillis();
                            long middle = end - begin;
                            if (middle > 86400000) {
                                logger.debug(subjobid + " " + "ip:" + ip + " timeout 86400000 " + middle);
//                                break;
                            } else {
                                logger.debug(subjobid + " " + "ip:" + ip + " not timeout 86400000 " + middle);
                            }
                            try {
                                Thread.sleep(10000);
                            } catch (InterruptedException ex) {
                                logger.error(ex.getMessage(), ex);
                            }
                        }
                    }
                    threadPool.shutdown();
                }

                long sum = jsonFiles.length;
                logger.info(subjobid + " **********************There are " + sum + " Jsonfiles totally, and " + complete + " Jsonfiles are successfully executed. ");
                rsMap.put("total", sum + "");
                rsMap.put("complete", complete + "");
                if (complete == sum && complete != 0 && sum != 0) {
                    rsMap.put("status", "success");
                    rsMap.put("desc", "ftpdownload execute successfully!");
                } else if (complete < sum && complete != 0 && sum != 0) {
                    rsMap.put("status", "half-success");
                    rsMap.put("desc", "ftpdownload half-successfully!");
                } else {
                    rsMap.put("status", "fail");
                    rsMap.put("desc", "ftpdownload execute unsuccessfully!");
                }
            }
        } else {
            logger.info(subjobid + " ip: " + ip + " the localPath " + localFilePath + "Ctrl does not have available JSON files.");
            logger.info(subjobid + "**********************json文件文件下载失败。");
        }
    }

    public void plusSucessUploadFileNumber() {
        complete = complete + 1;
    }

}
